package com.bocloud.cmp.service.resource;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.dao.CloudVendorDao;
import com.bocloud.cmp.dao.ImageDao;
import com.bocloud.cmp.dao.RegionDao;
import com.bocloud.cmp.driver.providers.intf.ImageProvider;
import com.bocloud.cmp.entity.resource.CloudVendor;
import com.bocloud.cmp.entity.resource.Image;
import com.bocloud.cmp.entity.resource.Region;
import com.bocloud.cmp.enums.VendorType;
import com.bocloud.cmp.interfaces.resource.ImageService;
import com.bocloud.cmp.model.ImageModel;
import com.bocloud.cmp.model.ImgBean;
import com.bocloud.cmp.model.SimpleImageBean;
import com.bocloud.cmp.service.model.OperateResult;
import com.bocloud.cmp.service.utils.ResourceEventPublisher;
import com.bocloud.common.model.BsmResult;
import com.bocloud.common.model.GridBean;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.SimpleBean;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.GridHelper;
import com.bocloud.coordinator.harmony.HarmonyLock;
import com.bocloud.coordinator.harmony.LockFactory;
import com.google.common.collect.Maps;

/**
 * 
 * 镜像实现类
 * 
 * @author DZG
 * @since V1.0 2016年9月13日
 */
@Service("imageService")
public class ImageServiceImpl implements ImageService {

	private static Logger logger = LoggerFactory.getLogger(ImageServiceImpl.class);
	@Autowired
	private ImageDao imageDao;
	@Autowired
	private RegionDao regionDao;
	@Autowired
	private CloudVendorDao cloudVendorDao;
	@Autowired
	private ImageProvider imageProvider;
	@Autowired
	private LockFactory lockFactory;
	@Autowired
	private ResourceEventPublisher resourceEventPublisher;

	@Override
	public BsmResult list(int page, int rows, List<Param> params, Map<String, String> sorter, Boolean simple) {
		List<Image> list = null;
		List<SimpleBean> beans = null;
		int total = 0;
		GridBean gridBean = null;
		try {
			if (null == sorter) {
				sorter = Maps.newHashMap();
			}
			sorter.put("id", Common.ONE);
			total = this.imageDao.count(params);
			if (simple) {
				beans = this.imageDao.list(params, sorter);
				gridBean = new GridBean(1, 1, total, beans);
			} else {
				list = this.imageDao.list(page, rows, params, sorter);
				for (Image image : list) {
					Region region = regionDao.query(image.getRegion());
					CloudVendor cloudVendor = cloudVendorDao.query(image.getVendorId());
					if (null != region) {
						image.setRegionName(region.getName());
					}
					if (null != cloudVendor) {
						image.setVendorName(cloudVendor.getName());
					}
				}
				gridBean = GridHelper.getBean(page, rows, total, list);
			}
			return new BsmResult(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("Query image list fail:", e);
			return new BsmResult(false, "查询失败", null, null);
		}
	}

	@Override
	public BsmResult detail(Long id) {
		try {
			Image image = imageDao.query(id);
			Region region = regionDao.query(image.getRegion());
			CloudVendor cloudVendor = cloudVendorDao.query(image.getVendorId());
			if (null != region) {
				image.setRegionName(region.getName());
			}
			if (null != cloudVendor) {
				image.setVendorName(cloudVendor.getName());
			}
			return new BsmResult(true, image, "查询成功!");
		} catch (Exception e) {
			logger.error("get image failure:", e);
			return new BsmResult(false, "查询失败!");
		}
	}

	@Override
	public BsmResult listName(Long id, Long region) {
		try {
			List<SimpleImageBean> images = imageDao.listName(id, region);
			return new BsmResult(true, images, "查询成功!");
		} catch (Exception e) {
			logger.error("list image failure:", e);
			return new BsmResult(false, "查询失败!");
		}
	}

	@Override
	public BsmResult listVersion(Long id, Long region, String name) {
		try {
			List<SimpleImageBean> images = imageDao.listVersion(id, region, name);
			return new BsmResult(true, images, "查询成功!");
		} catch (Exception e) {
			logger.error("list image failure:", e);
			return new BsmResult(false, "查询失败!");
		}

	}

	@Override
	public BsmResult remove(Long id, Long userId) {
		String path = Image.class.getSimpleName() + "_" + id;
		HarmonyLock lock = null;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时", "", "");
			}
			Image image = imageDao.query(id);
			if (null == image) {
				logger.warn("image data not exist");
				return new BsmResult(false, "数据不存在", "", "");
			}
			CloudVendor cloudVendor = cloudVendorDao.query(image.getVendorId());
			new Thread(new Runnable() {
				@Override
				public void run() {
					String operate = cloudVendor.getType().toLowerCase() + ".image";
					try {
						BsmResult bsmResult = null;
						VendorType type = VendorType.valueOf(cloudVendor.getType());
						switch (type) {
						case OPENSTACK:
							bsmResult = imageProvider.remove(image.getImageId(), cloudVendor.getUuid(), null, null);
							break;
						default:
							break;
						}
						if (null != bsmResult && bsmResult.isSuccess()) {
							imageDao.remove(id, userId);
						}
						resourceEventPublisher.send(new OperateResult(true, "删除成功!", operate));
					} catch (Exception e) {
						logger.error("Get Message Exception:", e);
						resourceEventPublisher.send(new OperateResult(false, "删除失败!", operate));
					}
				}
			}).start();
			return new BsmResult(true, "删除任务已经下发，正在执行……");
		} catch (Exception e) {
			logger.error("remove image fail:", e);
			return new BsmResult(false, "删除失败", "", "");
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}

	@Override
	public BsmResult modify(ImgBean bean, Long userId) {
		String path = Image.class.getSimpleName() + "_" + bean.getId();
		HarmonyLock lock = null;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时");
			}
			Image image = imageDao.query(bean.getId());
			if (null == image) {
				logger.warn("image does not exist!");
				return new BsmResult(false, "数据不存在!");
			}
			CloudVendor cloudVendor = cloudVendorDao.query(image.getVendorId());
			if (null == cloudVendor) {
				logger.error("get cloudVendor failure");
				return new BsmResult(false, "修改失败");
			}
			BeanUtils.copyProperties(bean, image);
			BsmResult bsmResult = imageProvider.modify(cloudVendor.getUuid(), null,
					JSONObject.parseObject(JSONObject.toJSONString(image), ImageModel.class));
			if (null == bsmResult || !bsmResult.isSuccess()) {
				return new BsmResult(false, "修改失败");
			}
			image.setMenderId(userId);
			imageDao.update(image);
			return new BsmResult(true, "修改成功");
		} catch (Exception e) {
			logger.error("Modify image fail:", e);
			return new BsmResult(false, "修改失败", null, null);
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}
}